﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;

namespace FileMonSync
{
    public class WatcherTimer
    {
        private int TimeoutMillis = 2000;

        FileSystemWatcher fsw = null;
        System.Threading.Timer m_timer = null;
        List<String> files = new List<string>();
        FileSystemEventHandler fswHandler = null;

        public WatcherTimer(FileSystemWatcher watcher,FileSystemEventHandler watchHandler)
        {
            m_timer = new System.Threading.Timer(new TimerCallback(OnTimer),
                         null, Timeout.Infinite, Timeout.Infinite);
            fsw = watcher;
            fswHandler = watchHandler;
            addHandlers();
        }

        private void addHandlers()
        {
            fsw.Created += new FileSystemEventHandler(OnFileChanged);
            fsw.Changed += new FileSystemEventHandler(OnFileChanged);
            fsw.Renamed += new RenamedEventHandler(OnFileChanged);
            fsw.Deleted += new FileSystemEventHandler(OnFileChanged);
        }

        public WatcherTimer(FileSystemEventHandler watchHandler)
        {
            m_timer = new System.Threading.Timer(new TimerCallback(OnTimer),
                         null, Timeout.Infinite, Timeout.Infinite);
            fswHandler = watchHandler;

        }


        public WatcherTimer(FileSystemEventHandler watchHandler, int timerInterval)
        {
            m_timer = new System.Threading.Timer(new TimerCallback(OnTimer),
                        null, Timeout.Infinite, Timeout.Infinite);
            TimeoutMillis = timerInterval;
            fswHandler = watchHandler;

        }

        public void OnFileChanged(object sender, FileSystemEventArgs e)
        {
            Mutex mutex = new Mutex(false, "FSW");
            mutex.WaitOne();
            if (!files.Contains(e.Name))
            {
                files.Add(e.Name);
            }
            mutex.ReleaseMutex();

            m_timer.Change(TimeoutMillis, Timeout.Infinite);
        }

        private void OnTimer(object state)
        {
            List<String> backup = new List<string>();

            Mutex mutex = new Mutex(false, "FSW");
            mutex.WaitOne();
            backup.AddRange(files);
            files.Clear();
            mutex.ReleaseMutex();


            foreach (string file in backup)
            {
                fswHandler(this, new FileSystemEventArgs(
                       WatcherChangeTypes.Changed, fsw.Path, file));
            }

        }



    }
}
